package org.jsola.hr.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.jsola.common.FileKit;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IAttendanceSallaryTemplateItemDAO;
import org.jsola.hr.dto.AttendanceSallaryTemplateAddDTO;
import org.jsola.hr.dto.AttendanceSallaryTemplateItemAddDTO;
import org.jsola.hr.dto.AttendanceSallaryTemplateItemUpdateDTO;
import org.jsola.hr.entity.AttendanceSallaryTemplateItemDO;
import org.jsola.hr.query.AttendanceDataTempQuery;
import org.jsola.hr.query.AttendanceSallaryTemplateItemQuery;
import org.jsola.hr.query.AttendanceSallaryTemplateQuery;
import org.jsola.hr.service.IAttendanceSallaryTemplateItemService;
import org.jsola.hr.service.IAttendanceSallaryTemplateService;
import org.jsola.hr.vo.AttendanceSallaryTemplateItemListVO;
import org.jsola.hr.vo.AttendanceSallaryTemplateItemVO;
import org.jsola.hr.vo.AttendanceSallaryTemplateListVO;
import org.jsola.hr.vo.AttendanceSallaryTemplateVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 考勤工资模板配置项表
 *
 * @author zhr
 */
@Service("hrAttendanceSallaryTemplateItemServiceImpl")
public class AttendanceSallaryTemplateItemServiceImpl implements IAttendanceSallaryTemplateItemService {

    @Autowired
    private IAttendanceSallaryTemplateItemDAO attendanceSallaryTemplateItemDAO;
    @Autowired
    private IAttendanceSallaryTemplateService attendanceSallaryTemplateService;

    @Override
    public AttendanceSallaryTemplateItemVO addConfig(AttendanceSallaryTemplateItemAddDTO attendanceSallaryTemplateItemAddDTO, TokenUser tokenUser) {
        AttendanceSallaryTemplateQuery attendanceSallaryTemplateQuery = new AttendanceSallaryTemplateQuery();
        attendanceSallaryTemplateQuery.setCompanyId(attendanceSallaryTemplateItemAddDTO.getCompanyId());
        List<AttendanceSallaryTemplateListVO> select = attendanceSallaryTemplateService.select(attendanceSallaryTemplateQuery, tokenUser.getSiteId());
        if(CollectionUtils.isEmpty(select)){
            throw new ParamException("没有新建考勤模板");
        }
        attendanceSallaryTemplateItemAddDTO.setAttendanceSallaryTemplateId(select.get(0).getId());
        return save(attendanceSallaryTemplateItemAddDTO,tokenUser);
    }

    @Override
    public Page<AttendanceSallaryTemplateItemListVO> queryTemplateInfoPage(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, TokenUser tokenUser) {
        //查询公司有没有模板，没有就默认新建一个
        AttendanceSallaryTemplateQuery attendanceSallaryTemplateQuery = new AttendanceSallaryTemplateQuery();
        attendanceSallaryTemplateQuery.setCompanyId(attendanceSallaryTemplateItemQuery.getCompanyId());
        List<AttendanceSallaryTemplateListVO> select = attendanceSallaryTemplateService.select(attendanceSallaryTemplateQuery, tokenUser.getSiteId());
        if(CollectionUtils.isEmpty(select)){
            AttendanceSallaryTemplateAddDTO attendanceSallaryTemplateAddDTO = new AttendanceSallaryTemplateAddDTO();
            attendanceSallaryTemplateAddDTO.setCompanyId(attendanceSallaryTemplateItemQuery.getCompanyId());
            AttendanceSallaryTemplateVO attendanceSallaryTemplateVO = attendanceSallaryTemplateService.save(attendanceSallaryTemplateAddDTO, tokenUser);
            AttendanceSallaryTemplateItemAddDTO attendanceSallaryTemplateItemAddDTO = new AttendanceSallaryTemplateItemAddDTO();
            attendanceSallaryTemplateItemAddDTO.setAttendanceSallaryTemplateId(attendanceSallaryTemplateVO.getId());
            attendanceSallaryTemplateItemAddDTO.setConfigurationName("工种");
            attendanceSallaryTemplateItemAddDTO.setConfigurationStatus("工种1");
            attendanceSallaryTemplateItemAddDTO.setSallaryImpact(new BigDecimal(500));
            attendanceSallaryTemplateItemAddDTO.setIsSystemConfigure(true);
            attendanceSallaryTemplateItemAddDTO.setSort(1);
            save(attendanceSallaryTemplateItemAddDTO,tokenUser);

            attendanceSallaryTemplateItemAddDTO = new AttendanceSallaryTemplateItemAddDTO();
            attendanceSallaryTemplateItemAddDTO.setAttendanceSallaryTemplateId(attendanceSallaryTemplateVO.getId());
            attendanceSallaryTemplateItemAddDTO.setConfigurationName("考勤");
            attendanceSallaryTemplateItemAddDTO.setConfigurationExplain("满勤");
            attendanceSallaryTemplateItemAddDTO.setConfigurationStatus("1");
            attendanceSallaryTemplateItemAddDTO.setSallaryImpact(new BigDecimal(100));
            attendanceSallaryTemplateItemAddDTO.setIsSystemConfigure(true);
            attendanceSallaryTemplateItemAddDTO.setSort(1);
            save(attendanceSallaryTemplateItemAddDTO,tokenUser);
            attendanceSallaryTemplateItemQuery.setAttendanceSallaryTemplateId(attendanceSallaryTemplateVO.getId());
        }else {
            attendanceSallaryTemplateItemQuery.setAttendanceSallaryTemplateId(select.get(0).getId());
        }
        return selectPage(attendanceSallaryTemplateItemQuery, tokenUser.getSiteId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer batchUpdate(AttendanceSallaryTemplateItemUpdateDTO attendanceSallaryTemplateItemUpdateDTO, TokenUser tokenUser) {
        int count = 0;
        if(CollectionUtils.isEmpty(attendanceSallaryTemplateItemUpdateDTO.getAttendanceSallaryTemplateItemUpdateDTOArrayList())){
            throw new ParamException("未指定具体需要修改的模板数据");
        }
        if(!CollectionUtils.isEmpty(attendanceSallaryTemplateItemUpdateDTO.getDeleteIds())){
            for (String deleteId : attendanceSallaryTemplateItemUpdateDTO.getDeleteIds()) {
                deleteByIds(tokenUser, deleteId);
            }
        }
        ArrayList<AttendanceSallaryTemplateItemUpdateDTO> list = attendanceSallaryTemplateItemUpdateDTO.getAttendanceSallaryTemplateItemUpdateDTOArrayList();
        for (AttendanceSallaryTemplateItemUpdateDTO sallaryTemplateItemUpdateDTO : list) {
            if(StringUtils.isEmpty(sallaryTemplateItemUpdateDTO.getConfigurationExplain())){
                sallaryTemplateItemUpdateDTO.setConfigurationExplain(" ");
            }
            if(!StringUtils.isEmpty(sallaryTemplateItemUpdateDTO.getId())){
                count += update(sallaryTemplateItemUpdateDTO,tokenUser);
            }else {
                List<AttendanceSallaryTemplateItemListVO> select = select(sallaryTemplateItemUpdateDTO.to(AttendanceSallaryTemplateItemQuery.class), tokenUser.getSiteId());
                if (select.size()>0){
                    throw new ParamException("重复定义配置项");
                }
                sallaryTemplateItemUpdateDTO.setIsSystemConfigure(false);
                AttendanceSallaryTemplateItemVO save = save(sallaryTemplateItemUpdateDTO.to(AttendanceSallaryTemplateItemAddDTO.class), tokenUser);
                if(save != null){
                    count++;
                }
            }

        }
        return count;
    }

    @Override
    public List<AttendanceSallaryTemplateItemListVO> getConfigByTempId(String attendanceSallaryTemplateId, TokenUser tokenUser) {
        return attendanceSallaryTemplateItemDAO.findConfigTypeCount(attendanceSallaryTemplateId, tokenUser.getSiteId());
    }

    @Override
    public InputStream downloadAttendanceSallaryTemplate(String attendanceSallaryTemplateId, TokenUser tokenUser) {
        //查所有配置项
        AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery = new AttendanceSallaryTemplateItemQuery();
        attendanceSallaryTemplateItemQuery.setAttendanceSallaryTemplateId(attendanceSallaryTemplateId);
        List<AttendanceSallaryTemplateItemListVO> templateInfoList = attendanceSallaryTemplateItemDAO.findConfigTypeCount(attendanceSallaryTemplateId, tokenUser.getSiteId());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        //制作表头
        List<List<String>> list = new ArrayList<List<String>>();
        int index = 0;
        for (int i = 0; i < 2 + 31 * templateInfoList.size(); i++) {
            ArrayList<String> list1 = new ArrayList<>();
            if(i == 0){
                list1.add("姓名");
                list1.add("姓名");
            }else if(i == 1){
                list1.add("手机");
                list1.add("手机");
            }else {
                list1.add((((i-2)/templateInfoList.size())+1)+"");
                list1.add(templateInfoList.get(index).getConfigurationName());
                index = index==templateInfoList.size()-1?0:index+1;
            }
            list.add(list1);
        }
        EasyExcel.write(outputStream)
                .head(list)
                .sheet("考勤工资记录")
                .doWrite(null);
        InputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
        return byteArrayInputStream;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer batchSave(AttendanceSallaryTemplateItemAddDTO attendanceSallaryTemplateItemAddDTO, TokenUser tokenUser) {
        int count = 0;
        for (AttendanceSallaryTemplateItemAddDTO sallaryTemplateItemAddDTO : attendanceSallaryTemplateItemAddDTO.getAttendanceSallaryTemplateItemAddDTOList()) {
            List<AttendanceSallaryTemplateItemListVO> select = select(sallaryTemplateItemAddDTO.to(AttendanceSallaryTemplateItemQuery.class), tokenUser.getSiteId());
            if (select.size()>0){
                throw new ParamException("已存在该配置名称");
            }
            sallaryTemplateItemAddDTO.setIsSystemConfigure(false);
            if(StringUtils.isEmpty(sallaryTemplateItemAddDTO.getConfigurationExplain())){
                sallaryTemplateItemAddDTO.setConfigurationExplain(" ");
            }
            AttendanceSallaryTemplateItemVO save = save(sallaryTemplateItemAddDTO, tokenUser);
            if(save != null){
                count++;
            }
        }
        return count;
    }

    @Override
    public Page<AttendanceSallaryTemplateItemListVO> getAttendanceSallaryTemplateInfo(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, TokenUser tokenUser) {
        //查询有没有模板，没有建立默认模板
        AttendanceSallaryTemplateQuery attendanceSallaryTemplateQuery = new AttendanceSallaryTemplateQuery();
        attendanceSallaryTemplateQuery.setCompanyId(attendanceSallaryTemplateItemQuery.getCompanyId());
        List<AttendanceSallaryTemplateListVO> select = attendanceSallaryTemplateService.select(attendanceSallaryTemplateQuery, tokenUser.getSiteId());
        Page<AttendanceSallaryTemplateItemListVO> page = new Page<>();
        ArrayList<AttendanceSallaryTemplateItemListVO> list = new ArrayList<>();
        if(select.size()==0){
            //添加默认模板
            AttendanceSallaryTemplateAddDTO attendanceSallaryTemplateAddDTO = new AttendanceSallaryTemplateAddDTO();
            attendanceSallaryTemplateAddDTO.setCompanyId(attendanceSallaryTemplateItemQuery.getCompanyId());
            attendanceSallaryTemplateAddDTO.setTemplateName(attendanceSallaryTemplateItemQuery.getCompanyName());
            AttendanceSallaryTemplateVO attendanceSallaryTemplateVO = attendanceSallaryTemplateService.save(attendanceSallaryTemplateAddDTO, tokenUser);
            //添加默认模板数据
            AttendanceSallaryTemplateItemAddDTO attendanceSallaryTemplateItemAddDTO = new AttendanceSallaryTemplateItemAddDTO();
            attendanceSallaryTemplateItemAddDTO.setAttendanceSallaryTemplateId(attendanceSallaryTemplateVO.getId());
            attendanceSallaryTemplateItemAddDTO.setConfigurationName("考勤状态");
            attendanceSallaryTemplateItemAddDTO.setConfigurationStatus("1");
            attendanceSallaryTemplateItemAddDTO.setConfigurationExplain("满勤");
            attendanceSallaryTemplateItemAddDTO.setSallaryImpact(new BigDecimal(0));
            attendanceSallaryTemplateItemAddDTO.setSort(1);
            attendanceSallaryTemplateItemAddDTO.setIsSystemConfigure(true);
            AttendanceSallaryTemplateItemVO data = save(attendanceSallaryTemplateItemAddDTO, tokenUser);
            list.add(data.to(AttendanceSallaryTemplateItemListVO.class));
            attendanceSallaryTemplateItemAddDTO = new AttendanceSallaryTemplateItemAddDTO();
            attendanceSallaryTemplateItemAddDTO.setAttendanceSallaryTemplateId(attendanceSallaryTemplateVO.getId());
            attendanceSallaryTemplateItemAddDTO.setConfigurationName("工种");
            attendanceSallaryTemplateItemAddDTO.setConfigurationStatus("焊A");
            attendanceSallaryTemplateItemAddDTO.setConfigurationExplain(" ");
            attendanceSallaryTemplateItemAddDTO.setSallaryImpact(new BigDecimal(0));
            attendanceSallaryTemplateItemAddDTO.setSort(1);
            attendanceSallaryTemplateItemAddDTO.setIsSystemConfigure(true);
            data= save(attendanceSallaryTemplateItemAddDTO, tokenUser);
            list.add(data.to(AttendanceSallaryTemplateItemListVO.class));
            page.setEntities(list);
            page.setEntityCount(list.size());
            page.setPageCount(1);
            page.setPageNo(attendanceSallaryTemplateItemQuery.getPageNo());
            page.setPageSize(attendanceSallaryTemplateItemQuery.getPageSize());
            return page;
        }
        com.github.pagehelper.Page<Object> page2 = PageHelper.startPage(attendanceSallaryTemplateItemQuery.getPageNo(), attendanceSallaryTemplateItemQuery.getPageSize());
        List<AttendanceSallaryTemplateItemListVO> select1 = attendanceSallaryTemplateItemDAO.selectBySort(select.get(0).getId(), tokenUser.getSiteId());
        page.setEntities(select1);
        page.setEntityCount((int)page2.getTotal());
        page.setPageCount(page2.getPages());
        page.setPageNo(attendanceSallaryTemplateItemQuery.getPageNo());
        page.setPageSize(attendanceSallaryTemplateItemQuery.getPageSize());
        return page;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public AttendanceSallaryTemplateItemVO save(AttendanceSallaryTemplateItemAddDTO attendanceSallaryTemplateItemAddDTO, TokenUser tokenUser) {
        if("考勤".equals(attendanceSallaryTemplateItemAddDTO.getConfigurationName())){
            if(!Validator.isNumber(attendanceSallaryTemplateItemAddDTO.getConfigurationStatus())){
                throw new ParamException("考勤配置项必须是纯数字");
            }
        }else if("工种".equals(attendanceSallaryTemplateItemAddDTO.getConfigurationName())){
            if(Validator.isNumber(attendanceSallaryTemplateItemAddDTO.getConfigurationStatus())){
                throw new ParamException("为了方便区别计算，工种的配置项不要配置成纯数字");
            }
        }
        //是否存在
        AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery = new AttendanceSallaryTemplateItemQuery();
        attendanceSallaryTemplateItemQuery.setAttendanceSallaryTemplateId(attendanceSallaryTemplateItemAddDTO.getAttendanceSallaryTemplateId());
        attendanceSallaryTemplateItemQuery.setConfigurationStatus(attendanceSallaryTemplateItemAddDTO.getConfigurationStatus());
        if(selectCount(attendanceSallaryTemplateItemQuery,tokenUser.getSiteId()) > 0){
            throw new ParamException("配置名称已存在");
        }

        // 转DO
        AttendanceSallaryTemplateItemDO attendanceSallaryTemplateItemDO = attendanceSallaryTemplateItemAddDTO.to(AttendanceSallaryTemplateItemDO.class);
        // 保存
        attendanceSallaryTemplateItemDO = save(attendanceSallaryTemplateItemDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return attendanceSallaryTemplateItemDO.to(AttendanceSallaryTemplateItemVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(AttendanceSallaryTemplateItemUpdateDTO attendanceSallaryTemplateItemUpdateDTO, TokenUser tokenUser) {
        //转DO
        AttendanceSallaryTemplateItemDO attendanceSallaryTemplateItemDO = attendanceSallaryTemplateItemUpdateDTO.to(AttendanceSallaryTemplateItemDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(attendanceSallaryTemplateItemDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... attendanceSallaryTemplateItemIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) attendanceSallaryTemplateItemIds);
    }


    @Override
    public AttendanceSallaryTemplateItemVO selectById(String attendanceSallaryTemplateItemId, String siteId) {
        AttendanceSallaryTemplateItemDO attendanceSallaryTemplateItemDO = selectDOById(attendanceSallaryTemplateItemId, siteId);
        if (attendanceSallaryTemplateItemDO == null) {
            return null;
        }
        return attendanceSallaryTemplateItemDO.to(AttendanceSallaryTemplateItemVO.class);
    }

    @Override
    public List<AttendanceSallaryTemplateItemListVO> select(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, String siteId) {
        List<AttendanceSallaryTemplateItemDO> attendanceSallaryTemplateItemDOList = selectDO(attendanceSallaryTemplateItemQuery, siteId);
        if(CollectionUtils.isEmpty(attendanceSallaryTemplateItemDOList)) {
            return attendanceSallaryTemplateItemDOList == null ? null : new ArrayList<>();
        }
        return attendanceSallaryTemplateItemDOList.stream()
                .map(attendanceSallaryTemplateItemDO -> attendanceSallaryTemplateItemDO.to(AttendanceSallaryTemplateItemListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, String siteId) {
        Example example = buildExample(attendanceSallaryTemplateItemQuery,siteId);
        return attendanceSallaryTemplateItemDAO.selectCountByExample(example);
    }

    @Override
    public Page<AttendanceSallaryTemplateItemListVO> selectPage(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, String siteId) {
        Example example = buildExample(attendanceSallaryTemplateItemQuery,siteId);
        Page<AttendanceSallaryTemplateItemDO> page = attendanceSallaryTemplateItemDAO.selectPageByExample(example,
                attendanceSallaryTemplateItemQuery.getPageNo(),
                attendanceSallaryTemplateItemQuery.getPageSize());

        return page.to(AttendanceSallaryTemplateItemListVO.class);
    }

    @Override
    public AttendanceSallaryTemplateItemDO selectDOById(String attendanceSallaryTemplateItemId, String siteId) {
        return listById(attendanceSallaryTemplateItemId, siteId);
    }

    @Override
    public List<AttendanceSallaryTemplateItemDO> selectDO(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, String siteId) {
        Example example = buildExample(attendanceSallaryTemplateItemQuery,siteId);
        return attendanceSallaryTemplateItemDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example

     * @param attendanceSallaryTemplateItemQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(AttendanceSallaryTemplateItemQuery attendanceSallaryTemplateItemQuery, String siteId) {
        Example example = new Example(AttendanceSallaryTemplateItemDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 排序
        if(!StringUtils.isEmpty(attendanceSallaryTemplateItemQuery.getAttendanceSallaryTemplateId())){
            example.and().andEqualTo("attendanceSallaryTemplateId",attendanceSallaryTemplateItemQuery.getAttendanceSallaryTemplateId());
        }
        if(!StringUtils.isEmpty(attendanceSallaryTemplateItemQuery.getConfigurationName())){
            example.and().andEqualTo("configurationName",attendanceSallaryTemplateItemQuery.getConfigurationName());
        }
        if(!StringUtils.isEmpty(attendanceSallaryTemplateItemQuery.getConfigurationStatus())){
            example.and().andEqualTo("configurationStatus",attendanceSallaryTemplateItemQuery.getConfigurationStatus());
        }
        if(attendanceSallaryTemplateItemQuery.getIsSystemConfigure() != null){
            example.and().andEqualTo("isSystemConfigure",attendanceSallaryTemplateItemQuery.getIsSystemConfigure());
        }
        ExampleKit.setExampleOrder(example,attendanceSallaryTemplateItemQuery.getOrders());
        return example;
    }
}




